home *** CD-ROM | disk | FTP | other *** search
- (c) Copyright 1989-1999 Amiga, Inc. All rights reserved.
- The information contained herein is subject to change without notice, and
- is provided "as is" without warranty of any kind, either expressed or implied.
- The entire risk as to the use of this information is assumed by the user.
-
-
-
-
- Simple Audio
-
- by Dan Baker
-
-
- The code shown below allows you to generate a tone with the Amiga's audio
- hardware. Use the frequency variable to set the pitch in Hz. Use the
- duration variable to set the duration of the tone in seconds.
-
- Audio device IO is handled mainly through the IOAudio structure which is
- defined in the audio.h header file. To make a tone, you open the audio
- device and send commands to it using the IOAudio structure. When you are
- finished, close the device.
-
- In the example below, most of the code is used to initialize fields in the
- IOAudio structure. For instance, the structure is filled in with channel
- allocation information just before the audio device is opened. This will
- cause a channel to be allocated automatically when the device is opened.
-
- The Amiga has a complex allocation and arbitration scheme which is
- described in detail in the ROM Kernel Manuals from Addison-Wesley. For
- now though just remember that the array whichannel[] tells the Amiga that
- you want any one of the four audio channels.
-
- After the audio device has been opened the IOAudio structure is initialized
- to play a note. In the example, AllocMem() is used to reserve two bytes of
- chip memory for the wave data which in this case is a very simple square wave.
- The address of the two byte sample is used in the IOAudio structure along with
- computed values for playback sampling rate, sample length and number of cycles.
-
- The command is sent to the audio device using BeginIO(). Once the command is
- sent, Wait() is called which puts the task to sleep untill the audio device
- has finished the command. Finally, GetMsg() is used to clear the reply from
- the audio device which is then closed with CloseDevice().
-
- In the example below, a 2 byte sample is used. To avoid aliasing distortion
- the length of the sample should be increased to 32 bytes and the period
- should be restricted to the range 124-256. This will limit the tones that
- can be produced to a one-octave range. You can find more information on
- aliasing distortion and other audio topics in the Amiga Hardware Manual and
- in the Amiga ROM Kernel Manuals, both published by Addison-Wesley.
-
-
-
-
-
- #include "exec/types.h"
- #include "exec/memory.h"
- #include "devices/audio.h"
- #include "graphics/gfxbase.h"
-
- struct GfxBase *GfxBase;
- struct Message *GetMsg();
- struct MsgPort *CreatePort();
- APTR OpenLibrary();
- APTR AllocMem();
- ULONG OpenDevice();
- UBYTE whichannel[] = { 1,2,4,8 };
-
- void
- main()
- {
- struct IOAudio *AudioIOBptr;
- struct MsgPort *port;
- struct Message *msg;
- BYTE *waveptr;
- ULONG device;
- LONG frequency=440; /* frequency of the tone */
- LONG duration =3; /* duration in seconds */
- LONG clock =3579545; /* Clock constant, 3546895 for PAL */
- LONG samples =2; /* Number of sample bytes */
-
-
- /*---------------------------------------*/
- /* Ask the system if we are PAL or NTSC */
- /* and set clock constant accordingly */
- /*---------------------------------------*/
- GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0L);
- if(GfxBase==0L) goto killaudio;
- if(GfxBase->DisplayFlags & PAL) clock=3546895; /* PAL clock */
- else clock=3579545; /* NTSC clock */
- if(GfxBase)CloseLibrary(GfxBase);
-
-
- /*------------------------------*/
- /* Allocate audio I/O blocks */
- /*------------------------------*/
- AudioIOBptr=(struct IOAudio *)
- AllocMem( sizeof(struct IOAudio),MEMF_PUBLIC | MEMF_CLEAR);
- if(AudioIOBptr==0) goto killaudio;
- printf("IO block allocated...\n");
-
-
- /*-----------------------------------------------*/
- /* Set up audio I/O block for channel allocation */
- /*-----------------------------------------------*/
- port=CreatePort(0,0);
- if(port==0) goto killaudio;
- printf("Port created...\n");
-
- AudioIOBptr->ioa_Request.io_Message.mn_ReplyPort = port;
- AudioIOBptr->ioa_Request.io_Message.mn_Node.ln_Pri = 0;
- AudioIOBptr->ioa_Request.io_Command = ADCMD_ALLOCATE;
- AudioIOBptr->ioa_Request.io_Flags = ADIOF_NOWAIT;
- AudioIOBptr->ioa_AllocKey = 0;
- AudioIOBptr->ioa_Data = whichannel;
- AudioIOBptr->ioa_Length = sizeof(whichannel);
- printf("IO block initialized for channel allocation...\n");
-
-
- /*-----------------------------------------------*/
- /* Open the audio device and allocate a channel */
- /*-----------------------------------------------*/
- device=OpenDevice("audio.device",0,AudioIOBptr,0);
- if(device!=0) goto killaudio;
- printf("Audio device opened, channel allocated...\n");
-
-
- /*-----------------------------------------*/
- /* Set up audio I/O block to make a sound. */
- /*-----------------------------------------*/
- waveptr=(BYTE *)AllocMem( samples , MEMF_CHIP|MEMF_PUBLIC);
- if(waveptr==0) goto killaudio;
- waveptr[0]= 127;
- waveptr[1]= -127;
- printf("Wave data ready...\n");
-
- AudioIOBptr->ioa_Request.io_Message.mn_ReplyPort = port;
- AudioIOBptr->ioa_Request.io_Command = CMD_WRITE;
- AudioIOBptr->ioa_Request.io_Flags = ADIOF_PERVOL;
- AudioIOBptr->ioa_Data = (BYTE *)waveptr;
- AudioIOBptr->ioa_Length = samples;
- AudioIOBptr->ioa_Period = clock/(samples*frequency);
- AudioIOBptr->ioa_Volume = 64;
- AudioIOBptr->ioa_Cycles = frequency*duration;
- printf("IO block initialized to play tone...\n");
-
- /*-----------------------------------*/
- /* Send the command to start a sound */
- /*-----------------------------------*/
- printf("Sarting tone now...\n");
- BeginIO(AudioIOBptr);
- Wait(1 << port->mp_SigBit);
- msg=GetMsg(port);
-
- printf("Sound finished...\n");
-
- killaudio:
-
- printf("Killing audio device...\n");
- if(waveptr!=0) FreeMem(waveptr, 2);
- if(port!=0) DeletePort(port);
- if(device==0) CloseDevice(AudioIOBptr);
- if(AudioIOBptr!=0) FreeMem( AudioIOBptr,sizeof(struct IOAudio) );
- }
-
-
-
-